package com.wss.module.main.ui.view;

import com.orhanobut.logger.Logger;
import com.wss.common.utils.AnimatorValueUtils;
import com.wss.common.utils.ColorUtils;
import com.wss.common.utils.PixelMapUtils;
import com.wss.common.utils.PxUtils;
import com.wss.module.main.ResourceTable;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.element.PixelMapElement;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.render.*;
import ohos.agp.utils.Color;
import ohos.agp.utils.Rect;
import ohos.agp.utils.TextAlignment;
import ohos.app.Context;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.eventhandler.InnerEvent;
import ohos.global.resource.NotExistException;
import ohos.global.resource.Resource;
import ohos.media.image.PixelMap;
import ohos.media.image.common.PixelFormat;

import java.io.IOException;

/**
 * Describe：人脸扫描动画浮层
 * Created by 吴天强 on 2020/11/20.
 */
public class FaceScanFloatView extends Component implements Component.DrawTask {

    /**
     * 动画时间
     */
    private static final int ANIM_TIME = 1000;
    /**
     * 圆心偏移量 正值 往下 负值往上
     */
    private static final int CIRCLE_OFFSET = 120;


    private Path mPath;
    /**
     * 圆圈属性动画
     */
    private AnimatorValue mAnimator;
    /**
     * 已完成之后提示文字的动画
     */
    private AnimatorValue completeAnimator;

    /**
     * 中心圆画笔
     */
    private Paint innerCirclePaint;
    /**
     * 外圆画笔
     */
    private Paint outerCirclePaint;
    /**
     * 提示文案画笔
     */
    private Paint textPaint;
    /**
     * 成功的Icon画笔
     */
    private Paint completeIconPaint;

    /**
     * 画提示文案的矩阵
     */
    private Rect textRect;
    /**
     * 圆圈以外区域背景颜色
     */
    private int mBackgroundColor = 0xAF000000;

    /**
     * 圆圈的最大半径
     */
    private int radius = 300;
    /**
     * 扫描完成显示的圆圈半径
     */
    private int completeRadius;
    /**
     * 提示文案
     */
    private String tipsText = "请正面面对摄像头";
    /**
     * 已完成的文案
     */
    private String completeText;
    /**
     * 俩圆间距
     */
    private int circleSpacing = 30;
    /**
     * 提示文案距离外圆间距
     */
    private int textToCircleSpacing = 100;

    private PixelMap completeBitMap;
    private boolean isComplete;

    public FaceScanFloatView(Context context) {
        super(context);
        init();
    }

    public FaceScanFloatView(Context context, AttrSet attrSet) {
        super(context, attrSet);
        init();
    }

    public FaceScanFloatView(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        init();
    }

    private void init() {
        innerCirclePaint = new Paint();
        innerCirclePaint.setStyle(Paint.Style.STROKE_STYLE);
        innerCirclePaint.setColor(new Color(
                getContext().getColor(ResourceTable.Color_transparent)
        ));
        innerCirclePaint.setStrokeWidth(PxUtils.vp2px(1));
        innerCirclePaint.setAntiAlias(true);

        outerCirclePaint = new Paint();
        outerCirclePaint.setStyle(Paint.Style.STROKE_STYLE);
        outerCirclePaint.setColor(new Color(
                getContext().getColor(ResourceTable.Color_theme)
        ));
        outerCirclePaint.setStrokeWidth(PxUtils.vp2px(1));
        outerCirclePaint.setAntiAlias(true);

        textPaint = new Paint();
        textPaint.setColor(new Color(
                getContext().getColor(ResourceTable.Color_white)
        ));
        textPaint.setTextSize(PxUtils.fp2px(16));
        textPaint.setTextAlign(TextAlignment.LEFT);

        completeIconPaint = new Paint();

        mPath = new Path();
        textRect = new Rect();
        mAnimator = new AnimatorValue();
        completeAnimator = new AnimatorValue();
        completeBitMap = PixelMapUtils.getPixelMapFromResource(getContext(),
                ResourceTable.Media_icon_loading);

        addDrawTask(this);
    }

    public void setBackgroundColor(final int color) {
        mBackgroundColor = color;
        RgbColor rgbColor = ColorUtils.colorToRgbColor(color);
        ShapeElement element = new ShapeElement();
        element.setRgbColor(rgbColor);
        setBackground(element);
        invalidate();
    }

    /**
     * 设置外圆的颜色
     *
     * @param color 颜色
     */
    public void setMaskPathColor(final int color) {
        outerCirclePaint.setColor(new Color(color));
        invalidate();
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        canvas.save();
        //计算圆心
        int circleX = getWidth() / 2;
        int circleY = getHeight() / 2 - CIRCLE_OFFSET;

        if (isComplete && radius <= completeRadius) {
            //完全圆设置画笔透明
            outerCirclePaint.setColor(new Color(
                    getContext().getColor(ResourceTable.Color_transparent)
            ));
            //画已完成的icon
            canvas.drawPixelMapHolder(new PixelMapHolder(
                            getCircleBitmap(completeBitMap,
                                    completeBitMap.getImageInfo().size.width,
                                    completeBitMap.getImageInfo().size.height)
                    ),
                    circleX - radius, circleY - radius, completeIconPaint);
            this.tipsText = completeText;
            if (isRotate) {
                handler.sendTimingEvent(MSG_ID, 16);
            }
        }
        //处理画布和中空内圆
        mPath.reset();
        mPath.addCircle(circleX, circleY, radius, Path.Direction.COUNTER_CLOCK_WISE);
        canvas.clipPath(mPath, Canvas.ClipOp.DIFFERENCE);
        canvas.drawColor(mBackgroundColor, BlendMode.SRC_OVER);
        canvas.restore();
        canvas.drawPath(mPath, innerCirclePaint);
        //添加外圆
        canvas.drawCircle(circleX, circleY, radius + circleSpacing, outerCirclePaint);

        //添加提示文案
        textRect = textPaint.getTextBounds(tipsText);
        int textX = getWidth() / 2 - textRect.getWidth() / 2;
        //文字的Y轴位置 = 圆心Y轴 + 圆半径 + 俩圆间距 +文字与圆间距
        int textY = circleY + radius + circleSpacing + textToCircleSpacing;
        canvas.drawText(textPaint, tipsText, textX, textY);
    }

    /**
     * 设置圆圈的最大半径
     *
     * @param radius 半径
     */
    public void setMaxRadius(int radius) {
        this.radius = radius;
        invalidate();
    }


    /**
     * 设置俩圆的间距
     *
     * @param circleSpacing 间距
     */
    public void setCircleSpacing(int circleSpacing) {
        this.circleSpacing = circleSpacing;
        invalidate();
    }

    /**
     * 设置提示文案距离外圆的间距
     *
     * @param textToCircleSpacing 间距
     */
    public void setTextToCircleSpacing(int textToCircleSpacing) {
        this.textToCircleSpacing = textToCircleSpacing;
        invalidate();
    }

    /**
     * 设置提示文案
     *
     * @param tipsText 提示文案
     */
    public void setTipsText(String tipsText) {
        this.tipsText = tipsText;
        invalidate();
    }

    /**
     * 设置提示文案颜色
     *
     * @param color 颜色
     */
    public void setTipsTextColor(int color) {
        textPaint.setColor(new Color(getContext().getColor(color)));
        invalidate();
    }

    /**
     * 设置提示文案大小
     *
     * @param size 大小
     */
    public void setTipsTextSize(int size) {
        textPaint.setTextSize(PxUtils.fp2px(size));
        invalidate();
    }

    /**
     * 设置是否完成
     */
    public void isComplete() {
        isComplete("");
    }

    /**
     * 设置是否完成
     *
     * @param tipsText 提示文案
     */
    public void isComplete(String tipsText) {
        this.isComplete = true;
        this.completeText = tipsText;
        //计算半径 已完成 中间空心圆半径为完成icon的半径
        completeRadius = completeBitMap.getImageInfo().size.width;
        startAnimator(radius, completeRadius);
        startCompleteAnimator();
    }


    /**
     * 设置完成的icon
     *
     * @param drawable icon
     */
    public void setCompleteImage(int drawable) {
        try {
            Resource resource = getContext().getResourceManager().getResource(drawable);
            PixelMapElement element = new PixelMapElement(resource);
            completeBitMap = element.getPixelMap();
            invalidate();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NotExistException e) {
            e.printStackTrace();
        }
    }

    /**
     * 开始动画
     */
    public void startAnimator() {
        startAnimator(radius, radius * 5 / 7);
    }

    /**
     * 开始动画
     *
     * @param maxRadius 最大半径
     * @param minRadius 最小半径
     */
    private void startAnimator(int maxRadius, int minRadius) {
        Logger.e("startAnimator");
        mAnimator = new AnimatorValue();
        mAnimator.setDuration(ANIM_TIME);
        mAnimator.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
            @Override
            public void onUpdate(AnimatorValue animatorValue, float v) {
                radius = (int) AnimatorValueUtils.getAnimatedValue(v, maxRadius, minRadius);
                System.out.println("==== radius : " + radius + " , v : " + v + " , max radius : " + maxRadius + " , min radius : " + minRadius);
                invalidate();
            }
        });
        mAnimator.start();
    }

    /**
     * 开始动画
     */
    private void startCompleteAnimator() {

        completeAnimator.setDuration(ANIM_TIME);
        completeAnimator.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
            @Override
            public void onUpdate(AnimatorValue animatorValue, float v) {
                textToCircleSpacing = (int) AnimatorValueUtils
                        .getAnimatedValue(v, textToCircleSpacing, 50);
                invalidate();
            }
        });
        completeAnimator.start();
    }

    private PixelMap bitmap;
    private boolean isCreateBitmap = false;
    private Canvas canvas;
    private Canvas.PorterDuffMode pdf;
    private Paint bitmapPaint;
    private float rotateSD = 0.8f;//每次旋转的角度--建议范围0.1f-1，否则会抖动
    private boolean isRotate = true;//控制是否旋转
    private final int MSG_ID = 0x101;

    private PixelMap getCircleBitmap(PixelMap image, int width, float rotate) {
        if (!isCreateBitmap) {
            //节约资源所以这些代码只需要执行一次
            bitmapPaint = new Paint();
            bitmapPaint.setAntiAlias(true);
            bitmapPaint.setDither(true);
            bitmap = PixelMapUtils.createBitmap(width, width, PixelFormat.ARGB_8888);
            isCreateBitmap = true;
            canvas = new Canvas();
            canvas.drawCircle(width / 2, width / 2, width / 2, bitmapPaint);
        }

        bitmapPaint.setBlendMode(BlendMode.SRC_OVER);
        canvas.rotate(rotate, width / 2, width / 2);
        canvas.drawPixelMapHolder(new PixelMapHolder(bitmap), 0, 0, bitmapPaint);
        bitmapPaint.setBlendMode(null);
        return bitmap;
    }

    private EventHandler handler = new MyHandler(EventRunner.getMainEventRunner());

    private class MyHandler extends EventHandler {

        public MyHandler(EventRunner runner) throws IllegalArgumentException {
            super(runner);
        }

        @Override
        protected void processEvent(InnerEvent event) {
            if (event.eventId == MSG_ID) {
                invalidate();
            }
        }
    }
}
